﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;

namespace WxApiLib
{
    //微信网页授权2.0
    public class Oauth2
    {
        JavaScriptSerializer Jss = new JavaScriptSerializer();
        public Oauth2() { }

        /// <summary>
        /// 拉取缓存的openid
        /// </summary>
        public string OpenidSession { get; set; }

        /// <summary>
        /// 对页面是否要用授权 
        /// </summary>
        /// <param name="Appid">微信应用id</param>
        /// <param name="redirect_uri">回调页面</param>
        /// <param name="scope">应用授权作用域snsapi_base（不弹出授权页面，直接跳转，只能获取用户openid），snsapi_userinfo （弹出授权页面，可通过openid拿到昵称、性别、所在地。并且，即使在未关注的情况下，只要用户授权，也能获取其信息）</param>
        /// <returns>授权地址</returns>
        public string GetCodeUrl(string Appid, string redirect_uri, string scope)
        {           
            string url= string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state=STATE#wechat_redirect", Appid, redirect_uri, scope);

            NetLog.WriteTextLog("验证", url, DateTime.Now);

            return url;
        }

        /// <summary>
        /// 用code换取openid 此方法一般是不获取用户昵称时候使用
        /// </summary>
        /// <param name="Appid"></param>
        /// <param name="Appsecret"></param>
        /// <param name="Code">回调页面带的code参数</param>
        /// <returns>微信用户唯一标识openid</returns>
        public string CodeGetOpenid(string Appid, string Appsecret, string Code)
        {
            string url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", Appid, Appsecret, Code);
            string ReText = Common.WebRequestPostOrGet(url, "");//post/get方法获取信息 
            NetLog.WriteTextLog("通过code获取的信息", ReText, DateTime.Now);
            Dictionary<string, object> DicText = (Dictionary<string, object>)Jss.DeserializeObject(ReText);
            if (!DicText.ContainsKey("openid"))
                return "";
            return DicText["openid"].ToString();
        }

        /// <summary>
        ///用code换取获取用户信息（包括非关注用户的）
        /// </summary>
        /// <param name="Appid"></param>
        /// <param name="Appsecret"></param>
        /// <param name="Code">回调页面带的code参数</param>
        /// <returns>获取用户信息（json格式）</returns>
        public string GetUserInfo(string Appid, string Appsecret, string Code)
        {
            string url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", Appid, Appsecret, Code);
            string ReText = Common.WebRequestPostOrGet(url, "");//post/get方法获取信息
            Dictionary<string, object> DicText = (Dictionary<string, object>)Jss.DeserializeObject(ReText);
            if (!DicText.ContainsKey("openid"))
            {
                Common.WriteTxt("获取openid失败，错误码：" + DicText["errcode"].ToString());
                return "";
            }
            else
            {
                return Common.WebRequestPostOrGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + DicText["access_token"] + "&openid=" + DicText["openid"] + "&lang=zh_CN", "");
            }
        }

        /// <summary>
        /// 获取关注用户列表的Json结果
        /// </summary>
        public class UserListJsonResult
        {
            /// <summary>
            /// 关注该公众账号的总用户数
            /// </summary>
            public int total { get; set; }

            /// <summary>
            /// 拉取的OPENID个数，最大值为10000
            /// </summary>
            public int count { get; set; }

            /// <summary>
            /// 列表数据，OPENID的列表
            /// </summary>
            public OpenIdListData data { get; set; }

            /// <summary>
            /// 拉取列表的后一个用户的OPENID
            /// </summary>
            public string next_openid { get; set; }
        }

        /// <summary>
        /// 列表数据，OPENID的列表
        /// </summary>
        public class OpenIdListData
        {
            /// <summary>
            /// OPENID的列表
            /// </summary>
            public List<string> openid { get; set; }
        }


        /// <summary>
        /// 高级接口获取的用户信息。
        /// 在关注者与公众号产生消息交互后，公众号可获得关注者的OpenID
        /// （加密后的微信号，每个用户对每个公众号的OpenID是唯一的。对于不同公众号，同一用户的openid不同）。
        /// 公众号可通过本接口来根据OpenID获取用户基本信息，包括昵称、头像、性别、所在城市、语言和关注时间。
        /// </summary>
        public class UserJson
        {
            /// <summary>
            /// 用户是否订阅该公众号标识，值为0时，代表此用户没有关注该公众号，拉取不到其余信息。
            /// </summary>
            public string subscribe { get; set; }

            /// <summary>
            /// 用户的标识，对当前公众号唯一
            /// </summary>
            public string openid { get; set; }

            /// <summary>
            /// 用户的昵称
            /// </summary>
            public string nickname { get; set; }

            /// <summary>
            /// 用户的性别，值为1时是男性，值为2时是女性，值为0时是未知
            /// </summary>
            public string sex { get; set; }

            /// <summary>
            /// 用户的语言，简体中文为zh_CN
            /// </summary>
            public string language { get; set; }

            /// <summary>
            /// 用户所在城市
            /// </summary>
            public string city { get; set; }

            /// <summary>
            /// 用户所在省份
            /// </summary>
            public string province { get; set; }

            /// <summary>
            /// 用户所在国家
            /// </summary>
            public string country { get; set; }

            /// <summary>
            /// 用户头像，最后一个数值代表正方形头像大小（有0、46、64、96、132数值可选，0代表640*640正方形头像），用户没有头像时该项为空
            /// </summary>
            public string headimgurl { get; set; }

            /// <summary>
            /// 用户关注时间，为时间戳。如果用户曾多次关注，则取最后关注时间
            /// </summary>
            public string subscribe_time { get; set; }

            public string remark { get; set; }
        }
    }
}
